
package me.liuhui.mall.manager.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import me.liuhui.mall.common.base.vo.ResultVO;
import me.liuhui.mall.manager.cache.RedisCache;
import me.liuhui.mall.manager.runtime.AdminSessionHolder;
import me.liuhui.mall.manager.service.RoleService;
import me.liuhui.mall.manager.service.convertor.RoleConverter;
import me.liuhui.mall.manager.service.dto.role.CreateRoleDTO;
import me.liuhui.mall.manager.service.dto.role.ListRoleDTO;
import me.liuhui.mall.manager.service.dto.role.ModifyRoleDTO;
import me.liuhui.mall.manager.service.vo.role.ListRoleVO;
import me.liuhui.mall.repository.mapper.AdminRoleMapper;
import me.liuhui.mall.repository.mapper.RoleMapper;
import me.liuhui.mall.repository.mapper.RolePermissionMapper;
import me.liuhui.mall.repository.model.AdminRole;
import me.liuhui.mall.repository.model.Role;
import me.liuhui.mall.repository.model.RolePermission;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static me.liuhui.mall.manager.utils.CacheConstants.ADMIN_PERMISSION_KEY;

/**
 * Created on 2020/10/14 20:12
 * <p>
 * Description: [TODO]
 * <p>
 * Company: []
 *
 * @author [清远]
 */
@Service
public class RoleServiceImpl implements RoleService {
    @Resource
    private RoleConverter roleConverter;
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private AdminRoleMapper adminRoleMapper;
    @Resource
    private RolePermissionMapper rolePermissionMapper;
    @Resource
    private RedisCache redisCache;

    @Override
    public ResultVO<ListRoleVO> list(ListRoleDTO dto) {
        LambdaQueryWrapper<Role> wrapper = Wrappers.lambdaQuery();
        Page<Role> page = new Page<>(dto.getPage(), dto.getLimit());
        Page<Role> rolePage = roleMapper.selectPage(page, wrapper);

        ListRoleVO vo = new ListRoleVO();
        vo.setTotal(rolePage.getTotal());
        vo.setList(roleConverter.toVo(rolePage.getRecords()));
        return ResultVO.success(vo);
    }

    @Override
    public ResultVO<Set<Long>> selectPermissionIds(Long id) {
        List<Long> codes = roleMapper.selectPermissionIds(id);
        return ResultVO.success(new HashSet<>(codes));
    }

    @Override
    public List<Role> currentRoles(Long adminId) {
        return roleMapper.selectRoleByAdminId(adminId);
    }

    @Override
    public ResultVO<Boolean> create(CreateRoleDTO dto) {
        Role entity = roleConverter.createDtoToEntity(dto);
        entity.setCreateTime(new Date());
        entity.setCreateAdmin(AdminSessionHolder.getCurrentAdmin().getUsername());
        roleMapper.insert(entity);
        for (Long permissionId : dto.getPermissionIds()) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setPermissionId(permissionId);
            rolePermission.setRoleId(entity.getId());
            rolePermissionMapper.insert(rolePermission);
        }
        return ResultVO.success();
    }

    @Override
    public ResultVO<Boolean> modify(ModifyRoleDTO dto) {
        Role role = roleMapper.selectById(dto.getId());
        if (role == null) {
            return ResultVO.buildFailResult("角色不存在");
        }
        Role entity = roleConverter.modifyDtoToEntity(dto);
        roleMapper.updateById(entity);
        rolePermissionMapper.deleteByRole(dto.getId());
        for (Long permissionId : dto.getPermissionIds()) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setPermissionId(permissionId);
            rolePermission.setRoleId(dto.getId());
            rolePermissionMapper.insert(rolePermission);
        }

        List<Long> adminIds = this.getAdminIdByRoleId(role.getId());
        for (Long adminId : adminIds) {
            redisCache.delete(ADMIN_PERMISSION_KEY + adminId);
        }
        return ResultVO.success();
    }

    private List<Long> getAdminIdByRoleId(Long roleId) {
        LambdaQueryWrapper<AdminRole> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(AdminRole::getRoleId, roleId);
        List<AdminRole> adminRoles = adminRoleMapper.selectList(wrapper);
        return adminRoles.stream().map(AdminRole::getAdminId).collect(Collectors.toList());
    }

    @Override
    public ResultVO<Boolean> delete(Set<Long> ids) {
        LambdaQueryWrapper<AdminRole> wrapper = Wrappers.lambdaQuery();
        wrapper.in(AdminRole::getRoleId, ids);
        Long count = adminRoleMapper.selectCount(wrapper);
        if (count > 0) {
            return ResultVO.buildFailResult("该角色有分配给管理员");
        }
        for (Long id : ids) {
            roleMapper.deleteById(id);
        }
        return ResultVO.success();
    }

}
